home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / cross / dasm202.lha / dasm-2.02 / exp.c < prev    next >
C/C++ Source or Header  |  1995-03-08  |  15KB  |  808 lines

  1.  
  2. /*
  3.  *  EXP.C
  4.  *
  5.  *  Handle expression evaluation and addressing mode decode.
  6.  *
  7.  *  NOTE! If you use the string field in an expression you must clear
  8.  *  the SYM_MACRO and SYM_STRING bits in the flags before calling
  9.  *  freesymbollist()!
  10.  */
  11.  
  12. #include "asm.h"
  13.  
  14. #define UNION    0
  15.  
  16. #if UNION        /* warning: ANSI disallows cast to union type */
  17. typedef void (unop)(long v1, int f1);
  18. typedef void (binop)(long v1, long v2, int f1, int f2);
  19.  
  20. union unibin {
  21.     unop *unary;
  22.     binop *binary;
  23. };
  24.  
  25. typedef union unibin opfunc_t;
  26. #define _unary    .unary
  27. #define _binary .binary
  28. #else            /* warning: Calling functions without prototype */
  29.  
  30. typedef void (*opfunc_t)();
  31. #define _unary
  32. #define _binary
  33.  
  34. #endif
  35.  
  36. void stackarg(long val, int flags);
  37.  
  38. void doop(opfunc_t, int pri);
  39. void evaltop(void);
  40. void    op_mult(long v1, long v2, int f1, int f2),
  41.     op_div(long v1, long v2, int f1, int f2),
  42.     op_mod(long v1, long v2, int f1, int f2),
  43.     op_add(long v1, long v2, int f1, int f2),
  44.     op_sub(long v1, long v2, int f1, int f2),
  45.     op_shiftleft(long v1, long v2, int f1, int f2),
  46.     op_shiftright(long v1, long v2, int f1, int f2),
  47.     op_greater(long v1, long v2, int f1, int f2),
  48.     op_greatereq(long v1, long v2, int f1, int f2),
  49.     op_smaller(long v1, long v2, int f1, int f2),
  50.     op_smallereq(long v1, long v2, int f1, int f2),
  51.     op_eqeq(long v1, long v2, int f1, int f2),
  52.     op_noteq(long v1, long v2, int f1, int f2),
  53.     op_andand(long v1, long v2, int f1, int f2),
  54.     op_oror(long v1, long v2, int f1, int f2),
  55.     op_xor(long v1, long v2, int f1, int f2),
  56.     op_and(long v1, long v2, int f1, int f2),
  57.     op_or(long v1, long v2, int f1, int f2),
  58.     op_question(long v1, long v2, int f1, int f2);
  59.  
  60. void    op_takelsb(long v1, int f1),
  61.     op_takemsb(long v1, int f1),
  62.     op_negate(long v1, int f1),
  63.     op_invert(long v1, int f1),
  64.     op_not(long v1, int f1);
  65.  
  66.  
  67. char *pushsymbol(char *str);
  68. char *pushstr(char *str);
  69. char *pushbin(char *str);
  70. char *pushoct(char *str);
  71. char *pushdec(char *str);
  72. char *pushhex(char *str);
  73. char *pushchar(char *str);
  74.  
  75. int alphanum(int c);
  76.  
  77. /*
  78.  *  evaluate an expression.  Figure out the addressing mode:
  79.  *
  80.  *        implied
  81.  *    #val    immediate
  82.  *    val    zero page or absolute
  83.  *    val,x    zero,x or absolute,x
  84.  *    val,y    zero,y or absolute,y
  85.  *    (val)    indirect
  86.  *    (val,x)    zero indirect x
  87.  *    (val),y    zero indirect y
  88.  *
  89.  *    exp, exp,.. LIST of expressions
  90.  *
  91.  *  an absolute may be returned as zero page
  92.  *  a relative may be returned as zero page or absolute
  93.  *
  94.  *  unary:  - ~ ! < >
  95.  *  binary: (^)(* / %)(+ -)(>> <<)(& |)(`)(&& ||)(== != < > <= >=)
  96.  *
  97.  *  values: symbol, octal, decimal, $hex, %binary, 'c "str"
  98.  *
  99.  */
  100.  
  101. #define MAXOPS        32
  102. #define MAXARGS     64
  103.  
  104. ubyte Argflags[MAXARGS];
  105. long  Argstack[MAXARGS];
  106. char *Argstring[MAXARGS];
  107. int Oppri[MAXOPS];
  108. opfunc_t Opdis[MAXOPS];
  109.  
  110. int    Argi, Opi, Lastwasop;
  111. int    Argibase, Opibase;
  112.  
  113. SYMBOL *
  114. eval(char *str, int wantmode)
  115. {
  116.     register SYMBOL *base, *cur;
  117.     int oldargibase = Argibase;
  118.     int oldopibase = Opibase;
  119.     int scr;
  120.  
  121.     Argibase = Argi;
  122.     Opibase = Opi;
  123.     Lastwasop = 1;
  124.     base = cur = allocsymbol();
  125.  
  126.     while (*str) {
  127.     if (Xdebug)
  128.         printf("char '%c'\n", *str);
  129.     switch(*str) {
  130.     case ' ':
  131.     case '\n':
  132.         ++str;
  133.         break;
  134.     case '~':
  135.         if (Lastwasop)
  136.         doop((opfunc_t)op_invert, 128);
  137.         else
  138.         asmerr(0,0);
  139.         ++str;
  140.         break;
  141.     case '*':
  142. #if OlafStar
  143.         if (Lastwasop) {
  144.         pushsymbol(".");
  145.         } else
  146. #endif
  147.         doop((opfunc_t)op_mult, 20);
  148.         ++str;
  149.         break;
  150.     case '/':
  151.         doop((opfunc_t)op_div, 20);
  152.         ++str;
  153.         break;
  154.     case '%':
  155.         if (Lastwasop) {
  156.         str = (char *)pushbin(str+1);
  157.         } else {
  158.         doop((opfunc_t)op_mod, 20);
  159.         ++str;
  160.         }
  161.         break;
  162.     case '?':   /*  10      */
  163.         doop((opfunc_t)op_question, 10);
  164.         ++str;
  165.         break;
  166.     case '+':   /*  19      */
  167.         doop((opfunc_t)op_add, 19);
  168.         ++str;
  169.         break;
  170.     case '-':   /*  19: -   (or - unary)        */
  171.         if (Lastwasop) {
  172.         doop((opfunc_t)op_negate, 128);
  173.         } else {
  174.         doop((opfunc_t)op_sub, 19);
  175.         }
  176.         ++str;
  177.         break;
  178.     case '>':   /*  18: >> <<  17: > >= <= <    */
  179.         if (Lastwasop) {
  180. #if OlafLt
  181.         if (SwapLessMore)
  182.             doop((opfunc_t)op_takelsb, 128);
  183.         else
  184.             doop((opfunc_t)op_takemsb, 128);
  185. #else
  186.         doop((opfunc_t)op_takelsb, 128);  /* SHOULD BE op_takemsb */
  187. #endif
  188.         ++str;
  189.         break;
  190.         }
  191.         if (str[1] == '>') {
  192.         doop((opfunc_t)op_shiftright, 18);
  193.         ++str;
  194.         } else if (str[1] == '=') {
  195.         doop((opfunc_t)op_greatereq, 17);
  196.         ++str;
  197.         } else {
  198.         doop((opfunc_t)op_greater, 17);
  199.         }
  200.         ++str;
  201.         break;
  202.     case '<':
  203.         if (Lastwasop) {
  204. #if OlafLt
  205.         if (SwapLessMore)
  206.             doop((opfunc_t)op_takemsb, 128);
  207.         else
  208.             doop((opfunc_t)op_takelsb, 128);
  209. #else
  210.         doop((opfunc_t)op_takemsb, 128);
  211. #endif
  212.         ++str;
  213.         break;
  214.         }
  215.         if (str[1] == '<') {
  216.         doop((opfunc_t)op_shiftleft, 18);
  217.         ++str;
  218.         } else if (str[1] == '=') {
  219.         doop((opfunc_t)op_smallereq, 17);
  220.         ++str;
  221.         } else {
  222.         doop((opfunc_t)op_smaller, 17);
  223.         }
  224.         ++str;
  225.         break;
  226.     case '=':   /*  16: ==  (= same as ==)      */
  227.         if (str[1] == '=')
  228.         ++str;
  229.         doop((opfunc_t)op_eqeq, 16);
  230.         ++str;
  231.         break;
  232.     case '!':   /*  16: !=                      */
  233.         if (Lastwasop) {
  234.         doop((opfunc_t)op_not, 128);
  235.         } else {
  236.         doop((opfunc_t)op_noteq, 16);
  237.         ++str;
  238.         }
  239.         ++str;
  240.         break;
  241.     case '&':   /*  15: &   12: &&              */
  242.         if (str[1] == '&') {
  243.         doop((opfunc_t)op_andand, 12);
  244.         ++str;
  245.         } else {
  246.         doop((opfunc_t)op_and, 15);
  247.         }
  248.         ++str;
  249.         break;
  250.     case '^':   /*  14: ^                       */
  251.         doop((opfunc_t)op_xor, 14);
  252.         ++str;
  253.         break;
  254.     case '|':   /*  13: |   11: ||              */
  255.         if (str[1] == '|') {
  256.         doop((opfunc_t)op_oror, 11);
  257.         ++str;
  258.         } else {
  259.         doop((opfunc_t)op_or, 13);
  260.         }
  261.         ++str;
  262.         break;
  263.     case '[':   /*  eventually an argument      */
  264.     bra:
  265.         if (Opi == MAXOPS)
  266.         puts("too many ops");
  267.         else
  268.         Oppri[Opi++] = 0;
  269.         ++str;
  270.         break;
  271.     case ']':
  272.     ket:
  273.         while(Opi != Opibase && Oppri[Opi-1])
  274.         evaltop();
  275.         if (Opi != Opibase)
  276.         --Opi;
  277.         ++str;
  278.         if (Argi == Argibase) {
  279.         puts("']' error, no arg on stack");
  280.         break;
  281.         }
  282.         if (*str == 'd') {  /*  STRING CONVERSION   */
  283.         char buf[32];
  284.         ++str;
  285.         if (Argflags[Argi-1] == 0) {
  286.             sprintf(buf,"%ld",Argstack[Argi-1]);
  287.             Argstring[Argi-1] = strcpy(malloc(strlen(buf)+1),buf);
  288.         }
  289.         }
  290.         break;
  291.     case '#':
  292.         cur->addrmode = AM_IMM8;
  293.         ++str;
  294.         break;
  295.     case '(':
  296. #if OlafBraKet
  297.         if (!wantmode)
  298.         goto bra;
  299. #endif
  300.         cur->addrmode = AM_INDWORD;
  301.         ++str;
  302.         break;
  303.     case ')':
  304. #if OlafBraKet
  305.         if (!wantmode)
  306.         goto ket;
  307. #endif
  308.         if (cur->addrmode == AM_INDWORD &&
  309.             str[1] == ',' && (str[2]|0x20) == 'y') {
  310.         cur->addrmode = AM_INDBYTEY;
  311.         str += 2;
  312.         }
  313.         ++str;
  314.         break;
  315.     case ',':
  316.         while(Opi != Opibase)
  317.         evaltop();
  318.         Lastwasop = 1;
  319.         scr = str[1]|0x20;      /* to lower case */
  320.         if (cur->addrmode == AM_INDWORD && scr == 'x' && !alphanum(str[2])) {
  321.         cur->addrmode = AM_INDBYTEX;
  322.         ++str;
  323.         } else if (scr == 'x' && !alphanum(str[2])) {
  324.         cur->addrmode = AM_0X;
  325.         ++str;
  326.         } else if (scr == 'y' && !alphanum(str[2])) {
  327.         cur->addrmode = AM_0Y;
  328.         ++str;
  329.         } else {
  330.         register SYMBOL *new = allocsymbol();
  331.         cur->next = new;
  332.         --Argi;
  333.         if (Argi < Argibase)
  334.             asmerr(0,0);
  335.         if (Argi > Argibase)
  336.             asmerr(0,0);
  337.         cur->value = Argstack[Argi];
  338.         cur->flags = Argflags[Argi];
  339.         if ((cur->string = (void *)Argstring[Argi]) != NULL) {
  340.             cur->flags |= SYM_STRING;
  341.             if (Xdebug)
  342.             printf("STRING: %s\n", cur->string);
  343.         }
  344.         cur = new;
  345.         }
  346.         ++str;
  347.         break;
  348.     case '$':
  349.         str = pushhex(str+1);
  350.         break;
  351.     case '\'':
  352.         str = pushchar(str+1);
  353.         break;
  354.     case '\"':
  355.         str = pushstr(str+1);
  356.         break;
  357.     default:
  358. #if OlafDol
  359.         {
  360.         char *dol = str;
  361.         while (*dol >= '0' && *dol <= '9')
  362.             dol++;
  363.         if (*dol == '$') {
  364.             str = pushsymbol(str);
  365.             break;
  366.         }
  367.         }
  368. #endif
  369.         if (*str == '0')
  370.         str = pushoct(str);
  371.         else {
  372.         if (*str > '0' && *str <= '9')
  373.             str = pushdec(str);
  374.         else
  375.             str = pushsymbol(str);
  376.         }
  377.         break;
  378.     }
  379.     }
  380.     while(Opi != Opibase)
  381.     evaltop();
  382.     if (Argi != Argibase) {
  383.     --Argi;
  384.     cur->value = Argstack[Argi];
  385.     cur->flags = Argflags[Argi];
  386.     if ((cur->string = (void *)Argstring[Argi]) != NULL) {
  387.         cur->flags |= SYM_STRING;
  388.         if (Xdebug)
  389.         printf("STRING: %s\n", cur->string);
  390.     }
  391.     if (base->addrmode == 0)
  392.         base->addrmode = AM_BYTEADR;
  393.     }
  394.     if (Argi != Argibase || Opi != Opibase)
  395.     asmerr(0,0);
  396.     Argi = Argibase;
  397.     Opi  = Opibase;
  398.     Argibase = oldargibase;
  399.     Opibase = oldopibase;
  400.     return(base);
  401. }
  402.  
  403. int
  404. alphanum(int c)
  405. {
  406.     return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  407.         (c >= '0' && c <= '9'));
  408. }
  409.  
  410. void
  411. evaltop(void)
  412. {
  413.     if (Xdebug)
  414.     printf("evaltop @(A,O) %d %d\n", Argi, Opi);
  415.     if (Opi <= Opibase) {
  416.     asmerr(0,0);
  417.     Opi = Opibase;
  418.     return;
  419.     }
  420.     --Opi;
  421.     if (Oppri[Opi] == 128) {
  422.     if (Argi < Argibase + 1) {
  423.         asmerr(0,0);
  424.         Argi = Argibase;
  425.         return;
  426.     }
  427.     --Argi;
  428.     (*Opdis[Opi]_unary)(Argstack[Argi], Argflags[Argi]);
  429.     } else {
  430.     if (Argi < Argibase + 2) {
  431.         asmerr(0,0);
  432.         Argi = Argibase;
  433.         return;
  434.     }
  435.     Argi -= 2;
  436.     (*Opdis[Opi]_binary)(Argstack[Argi], Argstack[Argi+1],
  437.                  Argflags[Argi], Argflags[Argi+1]);
  438.     }
  439. }
  440.  
  441. void
  442. stackarg(long val, int flags)
  443. {
  444.     char *str = NULL;
  445.  
  446.     if (Xdebug)
  447.     printf("stackarg %ld (@%d)\n", val, Argi);
  448.     Lastwasop = 0;
  449.     if (flags & SYM_STRING) {
  450.     unsigned char *ptr = (unsigned char *)str = (char *)val;
  451.     char *new;
  452.     int len;
  453.     val = len = 0;
  454.     while (*ptr && *ptr != '\"') {
  455.         val = (val << 8) | *ptr;
  456.         ++ptr;
  457.         ++len;
  458.     }
  459.     new = malloc(len + 1);
  460.     memcpy(new, str, len);
  461.     new[len] = 0;
  462.     flags &= ~SYM_STRING;
  463.     str = new;
  464.     }
  465.     Argstack[Argi] = val;
  466.     Argstring[Argi] = str;
  467.     Argflags[Argi] = flags;
  468.     if (++Argi == MAXARGS) {
  469.     puts("stackarg: maxargs stacked");
  470.     Argi = Argibase;
  471.     }
  472.     while (Opi != Opibase && Oppri[Opi-1] == 128)
  473.     evaltop();
  474. }
  475.  
  476. void
  477. doop(opfunc_t func, int pri)
  478. {
  479.     if (Xdebug)
  480.     puts("doop");
  481.     Lastwasop = 1;
  482.     if (Opi == Opibase || pri == 128) {
  483.     if (Xdebug)
  484.         printf("doop @ %d unary\n", Opi);
  485.     Opdis[Opi] = func;
  486.     Oppri[Opi] = pri;
  487.     ++Opi;
  488.     return;
  489.     }
  490.     while (Opi != Opibase && Oppri[Opi-1] && pri <= Oppri[Opi-1])
  491.     evaltop();
  492.     if (Xdebug)
  493.     printf("doop @ %d\n", Opi);
  494.     Opdis[Opi] = func;
  495.     Oppri[Opi] = pri;
  496.     ++Opi;
  497.     if (Opi == MAXOPS) {
  498.     puts("doop: too many operators");
  499.     Opi = Opibase;
  500.     }
  501.     return;
  502. }
  503.  
  504. void
  505. op_takelsb(long v1, int f1)
  506. {
  507.     stackarg(v1 & 0xFFL, f1);
  508. }
  509.  
  510. void
  511. op_takemsb(long v1, int f1)
  512. {
  513.     stackarg((v1 >> 8) & 0xFF, f1);
  514. }
  515.  
  516. void
  517. op_negate(long v1, int f1)
  518. {
  519.     stackarg(-v1, f1);
  520. }
  521.  
  522. void
  523. op_invert(long v1, int f1)
  524. {
  525.     stackarg(~v1, f1);
  526. }
  527.  
  528. void
  529. op_not(long v1, int f1)
  530. {
  531.     stackarg(!v1, f1);
  532. }
  533.  
  534. void
  535. op_mult(long v1, long v2, int f1, int f2)
  536. {
  537.     stackarg(v1 * v2, f1|f2);
  538. }
  539.  
  540. void
  541. op_div(long v1, long v2, int f1, int f2)
  542. {
  543.     if (f1|f2) {
  544.     stackarg(0L, f1|f2);
  545.     return;
  546.     }
  547.     if (v2 == 0) {
  548.     puts("division by zero");
  549.     stackarg(0L, 0);
  550.     } else {
  551.     stackarg(v1 / v2, 0);
  552.     }
  553. }
  554.  
  555. void
  556. op_mod(long v1, long v2, int f1, int f2)
  557. {
  558.     if (f1|f2) {
  559.     stackarg(0L, f1|f2);
  560.     return;
  561.     }
  562.     if (v2 == 0)
  563.     stackarg(v1, 0);
  564.     else
  565.     stackarg(v1 % v2, 0);
  566. }
  567.  
  568. void
  569. op_question(long v1, long v2, int f1, int f2)
  570. {
  571.     if (f1)
  572.        stackarg(0L, f1);
  573.     else
  574.     stackarg((long)((v1) ? v2 : 0), ((v1) ? f2 : 0));
  575. }
  576.  
  577. void
  578. op_add(long v1, long v2, int f1, int f2)
  579. {
  580.     stackarg(v1 + v2, f1|f2);
  581. }
  582.  
  583. void
  584. op_sub(long v1, long v2, int f1, int f2)
  585. {
  586.     stackarg(v1 - v2, f1|f2);
  587. }
  588.  
  589. void
  590. op_shiftright(long v1, long v2, int f1, int f2)
  591. {
  592.     if (f1|f2)
  593.     stackarg(0L, f1|f2);
  594.     else
  595.     stackarg((long)(v1 >> v2), 0);
  596. }
  597.  
  598. void
  599. op_shiftleft(long v1, long v2, int f1, int f2)
  600. {
  601.     if (f1|f2)
  602.     stackarg(0L, f1|f2);
  603.     else
  604.     stackarg((long)(v1 << v2), 0);
  605. }
  606.  
  607. void
  608. op_greater(long v1, long v2, int f1, int f2)
  609. {
  610.     stackarg((long)(v1 > v2), f1|f2);
  611. }
  612.  
  613. void
  614. op_greatereq(long v1, long v2, int f1, int f2)
  615. {
  616.     stackarg((long)(v1 >= v2), f1|f2);
  617. }
  618.  
  619. void
  620. op_smaller(long v1, long v2, int f1, int f2)
  621. {
  622.     stackarg((long)(v1 < v2), f1|f2);
  623. }
  624.  
  625. void
  626. op_smallereq(long v1, long v2, int f1, int f2)
  627. {
  628.     stackarg((long)(v1 <= v2), f1|f2);
  629. }
  630.  
  631. void
  632. op_eqeq(long v1, long v2, int f1, int f2)
  633. {
  634.     stackarg((long)(v1 == v2), f1|f2);
  635. }
  636.  
  637. void
  638. op_noteq(long v1, long v2, int f1, int f2)
  639. {
  640.     stackarg((long)(v1 != v2), f1|f2);
  641. }
  642.  
  643. void
  644. op_andand(long v1, long v2, int f1, int f2)
  645. {
  646.     if ((!f1 && !v1) || (!f2 && !v2)) {
  647.     stackarg(0L, 0);
  648.     return;
  649.     }
  650.     stackarg(1L, f1|f2);
  651. }
  652.  
  653. void
  654. op_oror(long v1, long v2, int f1, int f2)
  655. {
  656.     if ((!f1 && v1) || (!f2 && v2)) {
  657.     stackarg(1L, 0);
  658.     return;
  659.     }
  660.     stackarg(0L, f1|f2);
  661. }
  662.  
  663. void
  664. op_xor(long v1, long v2, int f1, int f2)
  665. {
  666.     stackarg(v1^v2, f1|f2);
  667. }
  668.  
  669. void
  670. op_and(long v1, long v2, int f1, int f2)
  671. {
  672.     stackarg(v1&v2, f1|f2);
  673. }
  674.  
  675. void
  676. op_or(long v1, long v2, int f1, int f2)
  677. {
  678.     stackarg(v1|v2, f1|f2);
  679. }
  680.  
  681. char *
  682. pushchar(char *str)
  683. {
  684.     if (*str) {
  685.     stackarg((long)*str, 0);
  686.     ++str;
  687.     } else {
  688.     stackarg((long)' ', 0);
  689.     }
  690.     return str;
  691. }
  692.  
  693. char *
  694. pushhex(char *str)
  695. {
  696.     register long val = 0;
  697.     for (;; ++str) {
  698.     if (*str >= '0' && *str <= '9') {
  699.         val = (val << 4) + (*str - '0');
  700.         continue;
  701.     }
  702.     if ((*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F')) {
  703.         val = (val << 4) + ((*str&0x1F) + 9);
  704.         continue;
  705.     }
  706.     break;
  707.     }
  708.     stackarg(val, 0);
  709.     return str;
  710. }
  711.  
  712. char *
  713. pushoct(char *str)
  714. {
  715.     register long val = 0;
  716.     while (*str >= '0' && *str <= '7') {
  717.     val = (val << 3) + (*str - '0');
  718.     ++str;
  719.     }
  720.     stackarg(val, 0);
  721.     return str;
  722. }
  723.  
  724. char *
  725. pushdec(char *str)
  726. {
  727.     register long val = 0;
  728.     while (*str >= '0' && *str <= '9') {
  729.     val = (val * 10) + (*str - '0');
  730.     ++str;
  731.     }
  732.     stackarg(val, 0);
  733.     return str;
  734. }
  735.  
  736. char *
  737. pushbin(char *str)
  738. {
  739.     register long val = 0;
  740.     while (*str == '0' || *str == '1') {
  741.     val = (val << 1) | (*str - '0');
  742.     ++str;
  743.     }
  744.     stackarg(val, 0);
  745.     return str;
  746. }
  747.  
  748. char *
  749. pushstr(char *str)
  750. {
  751.     stackarg((long)str, SYM_STRING);    /* warning: pointer to integer */
  752.     while (*str && *str != '\"')
  753.     ++str;
  754.     if (*str == '\"')
  755.     ++str;
  756.     return str;
  757. }
  758.  
  759. char *
  760. pushsymbol(char *str)
  761. {
  762.     register SYMBOL *sym;
  763.     register char *ptr;
  764.     ubyte macro = 0;
  765.  
  766.     for (ptr = str;
  767.     *ptr == '_' ||
  768.     *ptr == '.' ||
  769.     (*ptr >= 'a' && *ptr <= 'z') ||
  770.     (*ptr >= 'A' && *ptr <= 'Z') ||
  771.     (*ptr >= '0' && *ptr <= '9');
  772.     ++ptr
  773.     );
  774.     if (ptr == str) {
  775.     asmerr(9,0);
  776.     printf("char = '%c' %d (-1: %d)\n", *str, *str, *(str-1));
  777.     if (F_listfile)
  778.         fprintf(FI_listfile, "char = '%c' code %d\n", *str, *str);
  779.     return str+1;
  780.     }
  781. #if OlafDol
  782.     if (*ptr == '$')
  783.     ptr++;
  784. #endif
  785.     if ((sym = findsymbol(str, ptr - str)) != NULL) {
  786.     if (sym->flags & SYM_UNKNOWN)
  787.         ++Redo_eval;
  788.     if (sym->flags & SYM_MACRO) {
  789.         macro = 1;
  790.         sym = eval(sym->string, 0);
  791.     }
  792.     if (sym->flags & SYM_STRING)
  793.         stackarg((long)sym->string, SYM_STRING);    /* warning:ptr->int */
  794.     else
  795.         stackarg(sym->value, sym->flags & SYM_UNKNOWN);
  796.     sym->flags |= SYM_REF|SYM_MASREF;
  797.     if (macro)
  798.         freesymbollist(sym);
  799.     } else {
  800.     stackarg(0L, SYM_UNKNOWN);
  801.     sym = createsymbol(str, ptr - str);
  802.     sym->flags = SYM_REF|SYM_MASREF|SYM_UNKNOWN;
  803.     ++Redo_eval;
  804.     }
  805.     return(ptr);
  806. }
  807.  
  808.